package com.qijian.web.controller.system;

import cn.hutool.core.collection.CollectionUtil;
import com.qijian.common.annotation.Log;
import com.qijian.common.constant.UserConstants;
import com.qijian.common.core.controller.BaseController;
import com.qijian.common.core.domain.AjaxResult;
import com.qijian.common.core.domain.entity.SysMenu;
import com.qijian.common.core.domain.entity.SysUser;
import com.qijian.common.core.domain.model.LoginUser;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.SecurityUtils;
import com.qijian.common.utils.StringUtils;
import com.qijian.common.utils.file.AliyunOSSUtil;
import com.qijian.framework.web.service.TokenService;
import com.qijian.system.service.ISysConfigService;
import com.qijian.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * 个人信息 业务处理
 *
 * @author qijian
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController {

    private final ISysUserService userService;
    private final TokenService tokenService;
    private final ISysConfigService configService;

    /**
     * 个人信息
     */
    @GetMapping
    public AjaxResult profile() {
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        AjaxResult ajax = AjaxResult.success(user);
        ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
        ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
        return ajax;
    }



    public static Date getLastMonth(Date input) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(input);

        calendar.add(Calendar.MONTH, -1);
        Date previousMonthDate = calendar.getTime();

        return previousMonthDate;
    }

    /**
     * 修改用户
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult updateProfile(@RequestBody SysUser user) {
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                &&  userService.checkPhoneUnique(user) ) {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail())
                &&  userService.checkEmailUnique(user) ) {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        LoginUser loginUser = getLoginUser();
        SysUser sysUser = loginUser.getUser();
        user.setUserId(sysUser.getUserId());
        user.setPassword(null);
        if (userService.updateUserProfile(user) > 0) {
            // 更新缓存用户信息
            sysUser.setNickName(user.getNickName());
            sysUser.setPhonenumber(user.getPhonenumber());
            sysUser.setEmail(user.getEmail());
            sysUser.setSex(user.getSex());
            tokenService.setLoginUser(loginUser);
            return AjaxResult.success();
        }
        return AjaxResult.error("修改个人信息异常，请联系管理员");
    }

    /**
     * 重置密码
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping("/updatePwd")
    public AjaxResult updatePwd(String oldPassword, String newPassword) {
        LoginUser loginUser = getLoginUser();
        String userName = loginUser.getUsername();
        String password = loginUser.getPassword();
        if (!SecurityUtils.matchesPassword(oldPassword, password)) {
            return AjaxResult.error("修改密码失败，旧密码错误");
        }
        if (SecurityUtils.matchesPassword(newPassword, password)) {
            return AjaxResult.error("新密码不能与旧密码相同");
        }
        if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) {
            // 更新缓存用户密码
            loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
            tokenService.setLoginUser(loginUser);
            return AjaxResult.success();
        }
        return AjaxResult.error("修改密码异常，请联系管理员");
    }

    /**
     * 头像上传
     */
    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
    @PostMapping("/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            LoginUser loginUser = getLoginUser();
//            String avatar = FileUploadUtils.upload(QiJianConfig.getAvatarPath(), file);
            //改成上传oss
            String avatar = AliyunOSSUtil.uploadObject2OSS(AliyunOSSUtil.getOSSClient(), file,
                    "Avator", file.getName() + System.currentTimeMillis() + ".jpeg");

            if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) {
                AjaxResult ajax = AjaxResult.success();
                ajax.put("imgUrl", avatar);
                // 更新缓存用户头像
                loginUser.getUser().setAvatar(avatar);
                tokenService.setLoginUser(loginUser);
                return ajax;
            }
        }
        return AjaxResult.error("上传图片异常，请联系管理员");
    }

    @Log(title = "用户头像-上传", businessType = BusinessType.UPDATE)
    @PostMapping("/avatarUpload")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file, @RequestParam("userId") Long userId) throws IOException {
        if (!file.isEmpty()) {
            SysUser sysUser = userService.selectUserById(userId);
            if (Objects.isNull(sysUser)) {
                throw new ServiceException("E01:用户不存在");
            }
//            LoginUser loginUser = getLoginUser();
//            String avatar = FileUploadUtils.upload(QiJianConfig.getAvatarPath(), file);
            //改成上传oss
            String avatar = AliyunOSSUtil.uploadObject2OSS(AliyunOSSUtil.getOSSClient(), file,
                    "Avator", file.getName() + System.currentTimeMillis() + ".jpeg");
            //只返回用户头像地址，不更新用户信息
            AjaxResult ajax = AjaxResult.success();
            ajax.put("imgUrl", avatar);
            return ajax;
        }
        return AjaxResult.error("上传图片异常，请联系管理员");
    }

    /**
     * 获取待办
     *
     * @return /
     */
    @GetMapping(value = "/toDo")
    public AjaxResult toDo() {
//        Long userId = SecurityUtils.getUserId();
//        String userIdStr = SecurityUtils.getUserId().toString();
//        // 返回结果
//        Map<String, Long> result = new HashMap<>(8);
//        // 自定义流程
//        FlowableUserQuery userQuery = new FlowableUserQuery();
//        userQuery.setUserId(userId);
//        userQuery.setIsComplete(false);
//        Map<String, Long> dataNum = new HashMap<>(1);// flowableUserService.listVo(WhereEntityTool.invoke(userQuery)).stream().collect(Collectors.groupingBy(FlowableUserVo::getType, Collectors.counting()));
//        // fowable流程
//        TaskQuery taskQuery = taskService.createTaskQuery();
//        taskQuery.taskCategory(FlowableConstant.CATEGORY_TODO);
//        taskQuery.or().taskCandidateOrAssigned(userIdStr).taskOwner(userIdStr).endOr();
//        Map<String, Long> taskNum = new HashMap<>(1);//taskQuery.list().stream().collect(Collectors.groupingBy(TaskInfo::getCategory, Collectors.counting()));
//
//        // 查询菜单
//        SysMenu sysMenu = new SysMenu();
//        sysMenu.setShowType("app");
//        List<SysMenu> menuList = menuService.selectMenuTreeByUserId(userId, sysMenu);
//        Map<Long, String> parentMap = new HashMap<>(16);
//        // 待办事项计算
//        todoCheck(menuList, result, parentMap, dataNum, taskNum);
        return AjaxResult.data(new HashMap<>(8));
    }

    private void todoCheck(List<SysMenu> menuList, Map<String, Long> result, Map<Long, String> parentMap, Map<String, Long> dataNum, Map<String, Long> taskNum) {
        for (SysMenu menu : menuList) {
            parentMap.put(menu.getMenuId(), menu.getMenuName());
            if (StringUtils.isNotBlank(menu.getPending())) {
                String parentName = parentMap.get(menu.getParentId());
                Long num = dataNum.getOrDefault(menu.getPending(), 0L) + taskNum.getOrDefault(menu.getPending(), 0L);
                Long oldNum = result.get(menu.getMenuName());
                if (oldNum == null) {
                    oldNum = 0L;
                }
                result.put(menu.getMenuName(), num + oldNum);
                // 父级
                if (StringUtils.isNotBlank(parentName)) {
                    oldNum = result.get(parentName);
                    if (oldNum == null) {
                        oldNum = 0L;
                    }
                    result.put(parentName, num + oldNum);
                }
            }
            if (CollectionUtil.isNotEmpty(menu.getChildren())) {
                todoCheck(menu.getChildren(), result, parentMap, dataNum, taskNum);
            }
        }
    }
}
